From 724d3be794bc6faa79b9a17681fe77c67d280a99 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 25 Apr 2016 18:10:09 -0700 Subject: [PATCH] wayland: avoid jitter in keyboard repeat When synthesizing keyboard repeat, we can potentially drift further from the mark depending on the timing of the frame callback and how long it took to deliver the event. This patch attempts to reduce this by tracking from a stable epoch the time of our next keyboard repeat. https://bugzilla.gnome.org/show_bug.cgi?id=765567 --- gdk/wayland/gdkdevice-wayland.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 856437df51..c6823c1a15 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -177,6 +177,7 @@ struct _GdkWaylandSeat guint32 repeat_timer; guint32 repeat_key; guint32 repeat_count; + gint64 repeat_deadline; GSettings *keyboard_settings; uint32_t keyboard_time; @@ -1815,6 +1816,9 @@ deliver_key_event (GdkWaylandSeat *seat, GdkKeymap *keymap; xkb_keysym_t sym; guint delay, interval, timeout; + gint64 begin_time, now; + + begin_time = g_get_monotonic_time (); stop_key_repeat (seat); @@ -1862,10 +1866,20 @@ deliver_key_event (GdkWaylandSeat *seat, seat->repeat_count++; seat->repeat_key = key; + interval *= 1000L; + delay *= 1000L; + + now = g_get_monotonic_time (); + if (seat->repeat_count == 1) - timeout = delay; + seat->repeat_deadline = begin_time + delay; + else if (seat->repeat_deadline + interval > now) + seat->repeat_deadline += interval; else - timeout = interval; + /* frame delay caused us to miss repeat deadline */ + seat->repeat_deadline = now; + + timeout = (seat->repeat_deadline - now) / 1000L; seat->repeat_timer = gdk_threads_add_timeout (timeout, keyboard_repeat, seat); -- 2.30.2